#pragma once
#include"Connection.hpp"

class Acceptor {
    private:
        EventLoop *_loop;//⽤于对监听套接字进⾏事件监控
        TcpSocket _socket;//⽤于创建监听套接字
        Channel _listenChannel;//⽤于对监听套接字进⾏事件管理
        using AcceptCallback = std::function<void(int)>;
        AcceptCallback _accept_callback;//⽤于设置新连接的回调函数
    private:
        int CreateServer(int port)//创建监听套接字(调用TcpSocket的Build_Server_Socket函数)，从而获取监听描述符
        {
            _socket.Build_Server_Socket(port);
            return _socket.Fd();
        }
        void HandleRead()//处理监听套接字的可读事件(这里用于监听新连接)
        {
            struct sockaddr_in client_addr;
            int errnum = errno;
            int newfd = _socket.Accept((struct sockaddr *)&client_addr,&errnum);
            if(_accept_callback)
                _accept_callback(newfd);
        }
    public:
    /*不能将启动读事件监控，放到构造函数中，必须在设置回调函数后，再去启动*/
    /*否则有可能造成启动监控后，⽴即有事件，处理的时候，回调函数还没设置：新连接得不
    到处理，且资源泄漏*/
        Acceptor(EventLoop *loop,int port)
            : _loop(loop)
            ,_listenChannel(_loop, CreateServer(port))
        {
            _listenChannel.SetReadCallback(std::bind(&Acceptor::HandleRead, this));
        }
        void SetAcceptCallback(const AcceptCallback& cb)
        {
            _accept_callback = cb;
        }
        void Listen()
        {
            _loop->AddEvent(&_listenChannel);
            _listenChannel.EnableReading();
            _loop->ModifyEvent(&_listenChannel);
        }
        
};
